<?php

namespace Ysy\HyperfImport\Importer;

use Psr\Http\Message\UploadedFileInterface;
use Ysy\HyperfImport\Importer\Driver\CsvDriver;
use Ysy\HyperfImport\Importer\Driver\ExcelDriver;
use Ysy\HyperfImport\Importer\Driver\StreamExcelDriver;
use Ysy\HyperfImport\Importer\Validator\FileValidator;

class Importer
{
    protected array $drivers = [
        'xlsx' => ExcelDriver::class,
        'xls' => ExcelDriver::class,
        'csv' => CsvDriver::class
    ];

    // 流式驱动映射
    protected array $streamDrivers = [
        'xlsx' => StreamExcelDriver::class,
        'xls' => StreamExcelDriver::class,
    ];

    // 触发流式读取的阈值(10MB)
    protected int $streamingThreshold = 10 * 1024 * 1024;

    private FileValidator $fileValidator;

    public function __construct(FileValidator $fileValidator)
    {
        $this->fileValidator = $fileValidator;
    }

    /**
     * 读取文件（自动判断是否使用流式读取）
     * @param UploadedFileInterface $file
     * @param bool $skipHeader
     * @param array $options 支持配置: streaming_threshold(字节), read_all_sheets等
     * @param int $totalCount
     * @return \Generator
     */
    public function read(UploadedFileInterface $file, bool $skipHeader = true, array $options = [], int &$totalCount = 0 ): \Generator
    {
        $fileInfo = $this->fileValidator->validate($file);
        $filePath = $file->getRealPath();
        $extension = $fileInfo['extension'];
        
        // 获取自定义阈值
        $threshold = $options['streaming_threshold'] ?? $this->streamingThreshold;
        
        // 判断是否需要使用流式驱动
        $useStreaming = false;
        if (isset($this->streamDrivers[$extension]) && filesize($filePath) >= $threshold) {
            $useStreaming = true;
        }

        // 选择合适的驱动
        $driverClass = $useStreaming 
            ? $this->streamDrivers[$extension] 
            : $this->drivers[$extension];
            
        $driver = new $driverClass();
        
        return $driver->read($filePath, $extension, $skipHeader, $options, $totalCount);
    }
    
    /**
     * 手动指定使用流式驱动
     */
    public function readStream(UploadedFileInterface $file, bool $skipHeader = true, array $options = [], int &$totalCount = 0 ): \Generator
    {
        $fileInfo = $this->fileValidator->validate($file);
        $extension = $fileInfo['extension'];
        
        if (!isset($this->streamDrivers[$extension])) {
            throw new \RuntimeException("{$extension}格式不支持流式读取");
        }
        
        $driverClass = $this->streamDrivers[$extension];
        $driver = new $driverClass();
        
        return $driver->read($file->getRealPath(), $extension, $skipHeader, $options, $totalCount);
    }
}
    